const express = require("express");
const router = express.Router();
const { User } = require("../../models");
const { Op } = require("sequelize");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const crypto = require("crypto");
const { BadRequest, Unauthorized, NotFound } = require("http-errors");
const { success, failure } = require("../../utils/responses");
const validateCaptcha = require("../../middlewares/validate-captcha");
const { userSessions, userInfo } = require("../../utils/userInfo");
const service = require("../../utils/request");
const uuid = require("uuid");
const logger = require("../../utils/loggers");
const {
  snresultHandle,
  csxOneFinish,
  csxFinishAll,
  csxFree,
} = require("../chuanshuxian/index");
const {
  chengpinShuSongUrl,
  chengpinLoginData,
  loginRouterApi,
} = require("../../utils/config");

const { loginCreateToken } = require("../chuanshuxian/index");

// 生成 Token 和 Refresh Token
/**
 *
 * @param {*} user
 * @returns
 */
const generateTokens = async (user) => {
  const token = jwt.sign({ userId: user.id }, process.env.SECRET, {
    expiresIn: "48h",
  });
  const refreshToken = jwt.sign({ userId: user.id }, process.env.SECRET, {
    expiresIn: "30d",
  });
  return { token, refreshToken };
};

/**
 *
 * @param {*} req
 * @param {*} user
 */
async function sessionsHandler(req, res, user) {
  try {
    // 生成身份验证令牌
    const { token, refreshToken } = await generateTokens(user);
    console.log("Generated tokens:", { token, refreshToken }); // 添加日志

    // 生成sessionid
    const sessionId = uuid.v4();

    // 确保 req.session 已定义
    if (!req.session) {
      req.session = {};
    }

    if (userSessions[user.id]) {
      req.sessionStore.destroy(userSessions[user.id].sessionId, (err) => {
        if (err) {
          console.error("Error destroying session:", err);
        } else {
          console.log("Session destroyed successfully.");
        }
      });
    }

    // 将sessionId 存储在 req.session 中
    req.session.sessionId = sessionId;
    userSessions[user.id] = sessionId;

    // 直接返回token和refreshToken给前端
    // success(req, res, "登录成功。", {
    //   token,
    //   sessionId,
    //   refreshToken, // 确保refreshToken被返回
    // });

    loginOtherSystem(req, res, token, refreshToken, sessionId);
  } catch (error) {
    console.error("Error in sessionsHandler:", error);
    failure(req, res, error);
  }
}

/**
 * 登录其他系统
 */
function loginOtherSystem(req, res, token, refreshToken, sessionId) {
  // 成品输送线登录
  // success(req, res, "登录成功。", {
  //   token,
  //   sessionId,
  //   refreshToken, // 确保refreshToken被返回
  // });
  // return;
  loginCreateToken(chengpinLoginData)
    .then(async (response) => {
      logger.info(`成品输送线登录授权返回值,${JSON.stringify(response)}`);
      const acceptToken = response.result.accessToken;
      const refreshTokenCSX = response.result.refreshToken;

      // 设置 session 中的 AcceptToken
      req.session.AcceptToken = acceptToken;
      userSessions[acceptToken] = acceptToken;
      req.session.refreshTokenCSX = refreshTokenCSX;
      userSessions[refreshTokenCSX] = refreshTokenCSX;

      success(req, res, "登录成功。", {
        token,
        sessionId,
        refreshToken,
        acceptToken,
        refreshTokenCSX,
      });

      // 调用 csxFinishAll，现在它会自动从 session 获取 acceptToken
      // await csxFinishAll(req, "100259").then((response) => {
      //   logger.info(`传输线整体码垛完成${JSON.stringify(response)}`);
      // });
    })
    .catch((err) => {
      logger.error(`成品线登录失败${JSON.stringify(err)}`);
      failure(
        req,
        res,
        new BadRequest("获取成品输送线上位机权限失败，无法登录")
      );
    });
}

/**
 * 管理员登录
 * POST /admin/auth/sign_in
 */
router.post("/sign_in", validateCaptcha, async (req, res) => {
  try {
    // console.log(crypto.randomBytes(32).toString("hex"));

    const { login, password, type } = req.body;

    if (!login) {
      throw new BadRequest("邮箱/用户名必须填写。");
    }

    if (!password) {
      throw new BadRequest("密码必须填写。");
    }

    const condition = {
      where: {
        [Op.or]: [{ email: login }, { username: login }],
      },
    };

    // // 通过email或username，查询用户是否存在
    const user = await User.findOne(condition);
    console.log("user", user);
    if (!user) {
      throw new NotFound("用户不存在，无法登录。");
    }
    // 验证密码

    const isPasswordValid = bcrypt.compareSync(password, user.password);
    if (!isPasswordValid) {
      throw new Unauthorized("密码错误。");
    }
    // 验证是否管理员
    if (user.role !== 100) {
      throw new Unauthorized("您没有权限登录管理员后台。");
    }
    if (type && type != "1") {
      // 请求成功，删除验证码，防止重复使用
      await delKey(req.body.captchaKey);
    }
    sessionsHandler(req, res, user);
  } catch (error) {
    failure(req, res, error);
  }
});

// 刷新令牌
router.post("/refresh-token", async (req, res) => {
  try {
    const { refreshToken } = req.body;
    console.log("Received refreshToken:", refreshToken);
    console.log("Request body:", req.body);

    // 检查refreshToken是否存在
    if (!refreshToken) {
      return failure(req, res, new BadRequest("请提供刷新令牌。"));
    }

    // 检查refreshToken是否为字符串且非空
    if (typeof refreshToken !== "string" || refreshToken.trim() === "") {
      return failure(req, res, new BadRequest("刷新令牌格式无效。"));
    }

    // 验证refreshToken
    jwt.verify(refreshToken, process.env.SECRET, async (err, decoded) => {
      if (err) {
        console.log("refresh err", err);
        // 根据错误类型返回不同的错误信息
        if (err.name === "TokenExpiredError") {
          return failure(req, res, new BadRequest("刷新令牌已过期。"));
        } else if (err.name === "JsonWebTokenError") {
          return failure(req, res, new BadRequest("刷新令牌无效。"));
        } else {
          return failure(req, res, new BadRequest("刷新令牌验证失败。"));
        }
      }

      console.log("decoded user:", decoded);
      const { userId } = decoded;

      // 查询用户
      let user = await User.findByPk(userId);
      if (!user) {
        return failure(req, res, new NotFound("用户不存在。"));
      }

      // 生成新的token和refreshToken
      const { token, refreshToken: newRefreshToken } = await generateTokens(
        user
      );

      success(req, res, "刷新令牌成功。", {
        token,
        refreshToken: newRefreshToken,
      });
    });
  } catch (error) {
    console.error("Unexpected error in refresh token:", error);
    failure(req, res, error);
  }
});

// 登出
router.post("/sign_out", async (req, res) => {
  try {
    const { user } = await userInfo(req);
    if (userSessions[user.id]) {
      req.sessionStore.destroy(userSessions[user.id], (err) => {
        if (err) {
          console.error("Error destroying session:", err);
        } else {
          console.log("Session destroyed successfully.");
        }
      });
      delete userSessions[user.id];
    }
    success(req, res, "登出成功。");
  } catch (error) {
    failure(req, res, error);
  }
});

module.exports = router;
